<!-- 表格模版组件，无分页 -->
<template>
  <a-card class="table-card" size="small" :bordered="false">
    <!---------- 表格 begin ----------->
    <a-table
      :dataSource="tableData"
      :columns="processedColumns"
      :rowKey="rowKey"
      :loading="isLoading"
      :pagination="false"
      :scroll="{ x: 'max-content' }"
      bordered
      class="table-template"
    />
    <!---------- 表格 end ----------->

    <!---------- 分页 begin ----------->
    <div class="table-page">
      <a-pagination
        showSizeChanger
        showQuickJumper
        showLessItems
        :pageSizeOptions="PAGE_SIZE_OPTIONS"
        :defaultPageSize="PAGE_SIZE"
        v-model:current="pageData.pageNum"
        v-model:pageSize="pageData.pageSize"
        :total="total"
        @change="pageChange"
        @showSizeChange="pageChange"
        :showTotal="(total: number) => `共${total}条`"
      />
    </div>
    <!---------- 分页 end ----------->
  </a-card>
</template>
<script setup lang="tsx">
  import { ref, computed } from 'vue';
  import { type CustomTableColumnType } from '@/types/table'; //扩展 TableColumnType 定义
  import FlexButtons from '@/components/common/button/flex-buttons.vue'; //表格操作按钮模板
  import DropdownButtons from '@/components/common/button/dropdown-buttons.vue'; //表格操作按钮模板
  import { bizApi } from '@/api/biz';
  import { Flex, type TableColumnType } from 'ant-design-vue';
  import { isFunction } from 'lodash-es';

  const PAGE_SIZE = 2; //默认分页记录数
  const PAGE_SIZE_OPTIONS = ['1', '2', '5']; //可选分页配置

  const total = ref(0); //总页数，服务端返回

  /* 定义组件对外暴露接口 props */
  interface Props {
    columns: CustomTableColumnType[]; //表格列配置,调用组件传入
  }
  /* 配置 props 默认值 */
  const props = defineProps<Props>();

  const pageData: Record<string, any> = ref({
    page_num: 1, //当前页码
    page_size: PAGE_SIZE, //每页记录数
  });
  const rowKey = ref('id');
  const isLoading = ref(false); //表格加载状态 默认为false
  const tableData = ref([]); //表格数据
  const postParams = ref({}); //列表请求参数，调用组件传入
  const postAction = ref(''); //列表请求方法，调用组件传入
  /* 数据服务请求（访问服务端接口获取数据） */
  async function getTableData(action: string, params: Record<string, any>) {
    isLoading.value = true;
    try {
      postParams.value = params; //赋值给响应变量
      postAction.value = action; //赋值给响应变量
      const mergedParams = { ...postParams.value, ...pageData.value }; //合并分页参数

      const result = await bizApi.httpPage(postAction.value, mergedParams);

      tableData.value = result.records; //列表数据
      total.value = result.total_records; //记录总数
    } catch (error) {
      tableData.value = [];
      isLoading.value = false;
      return Promise.reject(error);
    }
    isLoading.value = false;
  }
  /* 翻页方法 */
  function pageChange(pageNum: number) {
    pageData.value.page_num = pageNum;
    getTableData(postAction.value, postParams.value);
  }

  /* 暴露接口供调用组件(父组件)使用 */
  defineExpose({
    getTableData,
  });

  /* 按钮点击事件，执行外部传入的 onClick 函数（闭包） */
  const btnItemClick = (btn: any, record: any, e?: Event) => {
    // 通用逻辑：权限校验
    console.log('btn.permission', btn.permission);

    e?.stopPropagation(); // 通用逻辑：阻止事件冒泡
    try {
      // 执行按钮原始点击回调
      if (typeof btn.onClick === 'function') {
        btn.onClick(record, e);
      }
    } catch (error) {
      // 捕获，未处理全局异常
      console.error(`【${btn.text}】操作执行失败：`, error);
    }
  };

  /* 枚举值映射为文本 */
  const mapEnumToText = (text: any, map: Record<any, string>) => {
    return map[text] || text;
  };

  /* 父组件定义的「列特征匹配规则」：根据列的特征自动应用默认属性 */
  const columnRules: { matcher: (col: CustomTableColumnType<any>) => boolean | undefined; defaults: TableColumnType }[] = [
    /* 规则：匹配 options 属性不为空（自定义属性） 不为空（存在）的列,存在则将 枚举值映射为文本值 */
    {
      matcher: (col: CustomTableColumnType<any>) => !!col.options, // 关键：判断 options 是否存在
      defaults: {
        width: 80, // 预设宽度（可根据需求调整）
        ellipsis: true, // 预设省略（避免文本溢出）
        align: 'center', // 预设居中（类型列常用）
        /* 枚举渲染：直接用列配置的 options，无默认值 */
        customRender: ({ text, column }: { text: string; column: any }) => {
          return mapEnumToText(text, column.options || {}); // 使用配置列的 options，无默认映射（空则返回原始值）
        },
      },
    },
    /* 规则：标题包含「排序」的列（如“菜单排序”“用户排序”）*/
    {
      matcher: (col: CustomTableColumnType<any>) => col.title?.toString().includes('排序'),
      defaults: {
        width: 30,
        align: 'center' as CustomTableColumnType['align'],
        ellipsis: true,
      },
    },
    /* 规则：简化按钮传入 */
    {
      matcher: (col: CustomTableColumnType<any>) => col.dataIndex === 'action',
      defaults: {
        title: '操作',
        fixed: 'right' as const,
        width: 120,
        align: 'center' as CustomTableColumnType['align'],
        ellipsis: false,
        /* 预设操作列渲染逻辑：自动渲染 TableActions，读取 buttons 数组 */
        customRender: ({ record, column: _column }) => {
          const column = _column as CustomTableColumnType;
          const colBUttons = (isFunction(column.buttons) ? column.buttons(record) : column.buttons) || [];
          /* 从列配置中获取 buttons 数组（使用侧传入的按钮配置） */
          const actionButtons = colBUttons.filter((btn) => !btn.more);
          const moreActionButtons = colBUttons.filter((btn) => btn.more);
          const buttons: any[] = actionButtons.map((btn) => ({
            ...btn,
            /* 若按钮的 onClick 依赖 record，自动注入 record（可选，增强灵活性） */
            onClick: (e?: Event) => btnItemClick(btn, record, e),
          }));
          const moreButtons: any[] = moreActionButtons.map((btn) => ({
            ...btn,
            /* 若按钮的 onClick 依赖 record，自动注入 record（可选，增强灵活性） */
            onClick: (e?: Event) => btnItemClick(btn, record, e),
          }));
          /* 渲染 TableActions 组件，传递 buttons 和 record（供点击事件使用） */
          return moreButtons.length ? (
            <Flex gap={8} align='center'>
              <FlexButtons buttons={buttons}></FlexButtons>
              <DropdownButtons buttons={moreButtons}></DropdownButtons>
            </Flex>
          ) : (
            <FlexButtons buttons={buttons}></FlexButtons>
          );
        },
      },
    },
    // 规则4：所有列的默认配置（优先级最低，仅当以上规则都不匹配时生效）
    {
      matcher: () => true, // 始终返回true，匹配所有列
      defaults: {
        ellipsis: true, // 所有列默认开启省略
        customHeaderCell() {
          return { style: { textAlign: 'center' } };
        },
      },
    },
  ];

  /* 处理列配置：根据规则自动添加默认属性（子组件配置优先级更高） */
  const processedColumns = computed<CustomTableColumnType<any>[]>(() => {
    return props.columns.map((col) => {
      const matchedRule = columnRules.find((rule) => rule.matcher(col)); // 找到匹配的规则
      if (matchedRule) {
        // 合并：子组件配置覆盖父组件默认值
        return { ...matchedRule.defaults, ...col };
      }
      return col; // 无匹配规则则返回原始配置
    });
  });
</script>
<style lang="less" scoped>
  .table-card {
    box-shadow: none;
    :deep(.ant-card-body) {
      padding: 0;
    }

    .table-page {
      text-align: end;
      margin-top: 20px;
    }
  }
</style>
